package org.k.reloadable.core.client;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.k.reloadable.core.Reloadable;
import org.k.reloadable.core.bean.Event;
import org.k.reloadable.core.bean.PropertyModifiedEvent;

/**
 * Created by hengxianwang on 16-12-20.
 */
public class ZKEventPublisher implements IEventPublisher {
    private Reloadable reloadable;

    public ZKEventPublisher(){
        this.startWatcher();
    }


    protected void startWatcher(){
        PathChildrenCache childrenCache = new PathChildrenCache(ZkClient.client, ZkClient.ROOT_NODE_NAME, true);
        PathChildrenCacheListener childrenCacheListener = new PathChildrenCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                ChildData data = event.getData();
                PropertyModifiedEvent propertyModifiedEvent = null;
                switch (event.getType()) {
                    case CHILD_ADDED:
                        propertyModifiedEvent = new PropertyModifiedEvent(data.getPath(), new String(data.getData()), Event.CREATE);
                        ZKEventPublisher.this.publish(propertyModifiedEvent);
                        break;
                    case CHILD_REMOVED:
                        propertyModifiedEvent = new PropertyModifiedEvent(data.getPath(), null, Event.DELETE);
                        ZKEventPublisher.this.publish(propertyModifiedEvent);
                        break;
                    case CHILD_UPDATED:
                        propertyModifiedEvent = new PropertyModifiedEvent(data.getPath(), new String(data.getData()), Event.UPDATE);
                        ZKEventPublisher.this.publish(propertyModifiedEvent);
                        break;
                    default:
                        break;
                }
            }
        };
        childrenCache.getListenable().addListener(childrenCacheListener);
        try {
            childrenCache.start();
        }catch (Exception e){
            //ignore
        }
    }

    @Override
    public void publish(PropertyModifiedEvent propertyModifiedEvent) {
        reloadable.change(propertyModifiedEvent);
    }

    public Reloadable getReloadable() {
        return reloadable;
    }

    public void setReloadable(Reloadable reloadable) {
        this.reloadable = reloadable;
    }
}
